package com.yuncool.jx3robot.mirai.config;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncool.jx3robot.common.constant.MiraiConst;
import com.yuncool.jx3robot.mirai.entily.BotSession;
import com.yuncool.jx3robot.mirai.mapper.BotSessionMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yuncool
 */
@ConfigurationProperties(prefix = "mirai")
@Configuration
@Data
@Slf4j
public class MiraiConfig {
    @Autowired
    BotSessionMapper botSessionMapper;
    private String key;
    private String qq;
    private String url;
    private String session;
    private String server;

    @PostConstruct
    public void init() {
        log.info("读取配置文件:url-{},key-{},qq-{}", url, key, qq);
        log.info("初始化mirai......");
        String res = HttpUtil.get(url + "/about");
        JSONObject resJson = JSONObject.parseObject(res);
        if (resJson.getInteger(MiraiConst.CODE).equals(MiraiConst.CodeEnum.SUCCESS.getCode())) {
            log.info("Mirai服务器版本信息:{}", resJson.getJSONObject(MiraiConst.DATA).toJSONString());
            //判断数据库中有没有session,有直接查出来
            BotSession botSession = botSessionMapper.selectOne(new LambdaQueryWrapper<BotSession>().eq(BotSession::getBotQq, qq));
            if (botSession != null) {
                log.info("已有session:{}", botSession.getSession());
                //校验是否失效了
                String s = HttpUtil.get(url + "/config?sessionKey=" + botSession.getSession());
                JSONObject jsonObject = JSONObject.parseObject(s);
                if (jsonObject.getInteger(MiraiConst.CODE) != null && jsonObject.getInteger(MiraiConst.CODE).equals(MiraiConst.CodeEnum.SESSION_INVALID.getCode())) {
                    //失效重新认证
                    authAndVerifySession();
                } else {
                    this.session = botSession.getSession();
                }
            } else {
                authAndVerifySession();
            }
        } else {
            throw new RuntimeException("mirai服务器链接失败....");
        }
    }

    /**
     * 认证和校验session
     * 连环套可抽取方法
     */
    private void authAndVerifySession() {
        Map<String, Object> params = new HashMap<>();
        params.put("authKey", key);
        HttpResponse resp = HttpUtil.createPost(url + "/auth").body(JSONObject.toJSONString(params)).execute();
        JSONObject resJson = JSONObject.parseObject(resp.body());
        log.info("authRep:{}", resJson.toJSONString());
        if (resJson.getInteger(MiraiConst.CODE).equals(MiraiConst.CodeEnum.SUCCESS.getCode())) {
            String repSession = resJson.getString("session");
            //校验session
            Map<String, Object> verify = new HashMap<>();
            verify.put("sessionKey", repSession);
            verify.put("qq", qq);
            HttpResponse resVerify = HttpUtil.createPost(url + "/verify").body(JSONObject.toJSONString(verify)).execute();
            JSONObject resVerifyJson = JSONObject.parseObject(resVerify.body());
            log.info("verifyRep:{}", resVerifyJson.toJSONString());
            if (resVerifyJson.getInteger(MiraiConst.CODE).equals(MiraiConst.CodeEnum.SUCCESS.getCode())) {
                //开启websocket
                Map<String, Object> config = new HashMap<>();
                config.put("sessionKey", repSession);
                config.put("enableWebsocket", true);
                HttpResponse resConfig = HttpUtil.createPost(url + "/config").body(JSONObject.toJSONString(config)).execute();
                JSONObject resConfigJson = JSONObject.parseObject(resConfig.body());
                log.info("configRep:{}", resConfigJson.toJSONString());
                if (resConfigJson.getInteger(MiraiConst.CODE).equals(MiraiConst.CodeEnum.SUCCESS.getCode())) {
                    //存入数据库
                    BotSession botSession = botSessionMapper.selectOne(new LambdaQueryWrapper<BotSession>().eq(BotSession::getBotQq, qq));
                    if (botSession != null) {
                        //session失效了
                        log.error("重新获取session:{},{}", repSession, botSession.getBotQq());
                        this.session = repSession;
                        botSession.setSession(repSession);
                        botSessionMapper.updateById(botSession);
//                        Map<String, Object> release = new HashMap<>();
//                        release.put("sessionKey", repSession);
//                        release.put("qq", botSession.getBotQq());
//                        HttpResponse resRelease = HttpUtil.createPost(url + "/release").body(JSONObject.toJSONString(release)).execute();
//                        JSONObject resReleaseJson = JSONObject.parseObject(resRelease.body());
//                        log.info("resReleaseJson:{}", resReleaseJson.toJSONString());
                    } else {
                        BotSession newBotSession = BotSession.builder().botQq(qq).session(repSession).build();
                        botSessionMapper.insert(newBotSession);
                        this.session = repSession;
                    }
                } else {
                    throw new RuntimeException("认证失败....");
                }
            } else {
                throw new RuntimeException("认证失败....");
            }
        } else {
            throw new RuntimeException("认证失败....");
        }
    }
}
